package com.haruhi.bot.endpoint.ws.client;

import com.haruhi.bot.endpoint.ws.model.MessageBox;
import com.haruhi.bot.endpoint.ws.MessageQueue;
import lombok.extern.slf4j.Slf4j;

import javax.websocket.ClientEndpointConfig;
import javax.websocket.CloseReason;
import javax.websocket.ContainerProvider;
import javax.websocket.EndpointConfig;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
import java.io.IOException;
import java.net.URI;
import java.util.concurrent.atomic.AtomicBoolean;

@Slf4j
public class ClientEndpoint implements WebSocketHandler {
    private static final WebSocketContainer webSocketContainer = ContainerProvider.getWebSocketContainer();

    private Session session;
    private final URI uri;
    private final ClientEndpointConfig configurator;
    private final long reconnectPeriod;
    private final ClientEndpointAdapter adapter;
    private final AtomicBoolean connecting = new AtomicBoolean(false);

    ClientEndpoint(URI url, ClientEndpointConfig configurator, long reconnectPeriod) {
        this.uri = url;
        this.configurator = configurator;
        this.reconnectPeriod = reconnectPeriod;
        this.adapter = new ClientEndpointAdapter(this);
    }

    public synchronized boolean connect() {
        try {
            if(session == null){
                session = webSocketContainer.connectToServer(adapter, configurator,uri);
            }
            return true;
        } catch (Exception e){
            log.info("连接失败 [{}]：[{}]",uri.toString(),e.getMessage());
            return false;
        }
    }
    public synchronized void reConnect(){
        log.info("开始重连：[{}]", uri.toString());
        if(!connecting.get()){
            connecting.set(true);
            new Thread(()->{
                while (true){
                    if(connect()){
                        connecting.set(false);
                        break;
                    }else {
                        try {
                            Thread.sleep(reconnectPeriod);
                        } catch (InterruptedException e) { }
                    }
                }
            }).start();
        }

    }

    @Override
    public void onOpen(Session session, EndpointConfig endpointConfig) {
        log.info("连接成功：[{}]",uri.toString());
    }


    @Override
    public void onMessage(Session session, String msg){
        log.info("收到消息：[{}] {}",uri.toString(),msg);
        MessageQueue.offer(new MessageBox(session,this,msg));
    }

    @Override
    public void onClose(Session session, CloseReason closeReason) {
        log.info("连接断开：[{}]",uri.toString());
        this.session = null;
        reConnect();
    }

    @Override
    public void onError(Session session, Throwable throwable) {
        log.info("连接异常：[{}]",uri.toString(),throwable);
        this.session = null;
        reConnect();
    }

    public synchronized void close(){
        if (this.session != null) {
            if (this.session.isOpen()) {
                try {
                    this.session.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            this.session = null;
        }
    }
}
